
package it.massetti.scoponescientifico.game;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PointsManager {

	private Map<Team, Integer> points = new HashMap<Team, Integer>();
	
	public void calculatePoints(List<Team> teams) {
		points.clear();
		calculateScope(teams);
		calculateCards(teams);
		calculateGolds(teams);
		calculatePrime(teams);
		// End of computation of points, let's add them
		for (Team current : teams) {
			current.setPoints(points.get(current));
		}
	}
	
	/**
	 * Calculate the point for the Prime
	 * @param teams
	 */
	private void calculatePrime(List<Team> teams) {
		Team majorPrime=null;
		int majorPrimePoints=0;
		int primePoints = 0;
		for(Team current : teams) {
			primePoints = calculatePrimePoints(current);
			if(primePoints>majorPrimePoints) {
				majorPrime=current;
				majorPrimePoints=primePoints;
			}
		}	
		try {
			updateTeamPoints(majorPrime, 1);
		} catch (NullPointerException e) {
		}
	}

	/**
	 * Calculate the prime points
	 * @param current
	 * @return
	 */
	private int calculatePrimePoints(Team current) {
		Map<Suit, Integer> points = new HashMap<Suit, Integer>();
		for (Card currentCard : current.getCards()) {
			int pointsToAdd=0;
			switch (currentCard.number) {
			case KING:
			case QUEEN:
			case JACK:
				pointsToAdd=10;
				break;
			case TWO:
				pointsToAdd=12;
				break;
			case THREE:
				pointsToAdd=13;
				break;
			case FOUR:
				pointsToAdd=14;
				break;
			case FIVE:
				pointsToAdd=15;
				break;
			case ACE:
				pointsToAdd=16;
				break;
			case SIX:
				pointsToAdd=18;
				break;
			case SEVEN:
				pointsToAdd=21;
				break;
			}
			int pointsForSuit;
			try {
				pointsForSuit = points.get(currentCard.suit);
			} catch (NullPointerException e) {
				pointsForSuit = 0;
			}
			if (pointsToAdd > pointsForSuit) {
				points.put(currentCard.suit, pointsToAdd);
			}
		}
		int primeSum=0;
		for(Suit currentSuit: Suit.values()) {
			primeSum = primeSum + points.get(currentSuit);
		}
		return primeSum;
	}

	/**
	 * Calculate the cards
	 * @param teams
	 */
	private void calculateCards(List<Team> teams) {
		Team majorCardTeam=null;
		int majorCardSize=0;
		for(Team current : teams) {
			if(current.getCards().size()>majorCardSize) {
				majorCardTeam=current;
				majorCardSize=current.getCards().size();
			}
		}	
		try {
			updateTeamPoints(majorCardTeam, 1);
		} catch (NullPointerException e) {
			
		}
	}
	
	/**
	 * Calculate the golds + 7 of gold
	 * @param teams
	 */
	private void calculateGolds(List<Team> teams) {
		Team majorGoldTeam=null;
		int majorGoldSize=0;
		for(Team current : teams) {
			int goldSize = 0;
			for (Card currentCard : current.getCards()) {
				if (currentCard.suit==Suit.DIAMONDS) {
					goldSize++;
					if(currentCard.number==Number.SEVEN) {
						updateTeamPoints(current, 1);						
					}
				}
			}
			if(goldSize>majorGoldSize) {
				majorGoldTeam=current;
				majorGoldSize=goldSize;
			}
		}	
		try {
			updateTeamPoints(majorGoldTeam, 1);
		} catch (NullPointerException e) {
		}
	}

	/**
	 * Update the team points
	 * @param team
	 * @param pointsToGive
	 */
	private void updateTeamPoints(Team team, int pointsToGive) {
		int oldPoints = points.get(team);
		pointsToGive = oldPoints + pointsToGive;
		points.put(team, pointsToGive);
	}

	/**
	 * Calculate the scopes
	 * @param teams
	 */
	private void calculateScope(List<Team> teams) {
		for(Team current : teams) {
			int scope = current.getScope();
			updateTeamPoints(current, scope);
		}
	}
}
